package iactor

import "fmt"

const (
	Actor_Uid = iota
	Actor_Name
	Actor_Type
	actor_Max
)

type IActor interface {
	GetActor() IActor
	InitIActor(...interface{}) interface{}
	DestoryActor()
}

type Actor struct {
	attr      []string
	chan_recv chan []interface{}
	chan_send chan []byte
	init      bool
}

func NewActor(args ...interface{}) *Actor {
	act := &Actor{}
	act.InitIActor(args...)
	return act
}

func DestoryActor(iact IActor) {
	//	Actor Desotry
	iact.GetActor().DestoryActor()
	//	object Destory
	iact.DestoryActor()
}

func (my *Actor) GetActor() IActor {
	return my
}

func (my *Actor) InitIActor(args ...interface{}) interface{} {
	if len(args) > 0 {
		// fmt.Println(my.init, args)
		if !my.init {
			my.attr = make([]string, actor_Max)
			Set(my, Actor_Uid, args[0].(string))
			Set(my, Actor_Type, args[1].(string))
			Set(my, Actor_Name, args[1].(string)+"_"+args[0].(string))
			my.chan_recv = make(chan []interface{}, 100)
			my.chan_send = make(chan []byte, 100)
			my.init = true
		} else {
			fmt.Printf("%s 需要进行传参初始化,请在对象中自定义 InitIActor\n", Type(my))
		}
	}

	return nil
}

func (my *Actor) DestoryActor() {
	// fmt.Println("dess")
	if my.init {
		close(my.chan_recv)
		close(my.chan_send)
		my.chan_recv = nil
		my.chan_send = nil
		my.init = false
	} else {
		panic("over")
	}
}

func Push(i_act IActor, args ...interface{}) {
	act := i_act.GetActor().(*Actor)
	act.chan_recv <- args
}

func Pop(i_act IActor) ([]interface{}, bool) {
	act := i_act.GetActor().(*Actor)
	// fmt.Println(act)
	resp, life := <-act.chan_recv
	return resp, life
}

func Get(i_act IActor, act_type int32) *string {
	act := i_act.GetActor().(*Actor)
	if act_type >= actor_Max {
		return nil
	}
	return &act.attr[act_type]
}

func Set(i_act IActor, act_type int32, act_value string) bool {
	act := i_act.GetActor().(*Actor)
	if act_type >= actor_Max {
		return false
	}

	act.attr[act_type] = act_value
	// fmt.Println("sffff", act.attr[act_type])
	return true
}

func Uid(i_act IActor) string {
	act := i_act.GetActor().(*Actor)
	return act.attr[Actor_Uid]
}

func Name(i_act IActor) string {
	act := i_act.GetActor().(*Actor)
	return act.attr[Actor_Name]
}

func Type(i_act IActor) string {
	act := i_act.GetActor().(*Actor)
	return act.attr[Actor_Type]
}
